// 纯函数
// let numbers = [1, 2, 3, 4, 5] 
// // 纯函数
//  let m1=numbers.slice(0, 3) // => [1, 2, 3] 
//  let m2=numbers.slice(0, 3) // => [1, 2, 3] 
//  let m3=numbers.slice(0, 3) // => [1, 2, 3] 
//  console.log(m1)
//  console.log(m2)
//  console.log(m3)
 
//  function getSum (n1,n2){
//      return n1 + n2
//  }
//  console.log(getSum(1,2))

// lodash
//first /last /toUpper /reverse / each /includes /find /findIndex
// const _ =require('lodash')

// const array = ['jack','tom','luck','calse']
// console.log(_.first(array))
// console.log(_.last(array))
// console.log(_.toUpper(_.first(array)))
// // console.log(_.reverse(array))
// const r = _.each(array,(item,index)=>{
//     console.log(item,index)
// })

// 记忆函数
// const _ =require('lodash')
// function getArea(r){
//     console.log(r)
//     return Math.PI*r*r
// }
// _.memoize(纯函数)  //会缓存一个纯函数
// let getAreaWithMemory = _.memoize(getArea)
// console.log(getAreaWithMemory(4))
// console.log(getAreaWithMemory(4))
// console.log(getAreaWithMemory(4))

//模拟memoize 方法的实现

// function memoize(f){
//     let cache = {}
//     return function(){
//      let key = JSON.stringify(arguments)
//      cache[key] = cache[key] ||f.apply(f,arguments)
//      return cache[key]
//     }
// }

//  let getAreaWithMemory = memoize(getArea)
// console.log(getAreaWithMemory(4))
// console.log(getAreaWithMemory(4))
// console.log(getAreaWithMemory(4))

// 柯里化
// function checkAge (age) { 
//     let min = 18
//     return age >= min 
// }
// 普通的纯函数
// function checkAge (min,age) { 
//     return age >= min 
// }

// console.log(checkAge(18, 24) )
// console.log(checkAge(18, 20))
// console.log(checkAge(20, 30))
//  函数柯里化
// function checkAge (min) { 
//     return function(age){
//         return age >= min
//     } 
// }
// // es6
// let checkAge = min =>(age =>age >=min)

// let checkAge18 = checkAge(18)
// let checkAge20 = checkAge(20)
// console.log(checkAge18(20))
// console.log(checkAge20(24))

// const _ =require('lodash')
// function getSum(a,b,c){
  
//     return  a + b +c
// }
// // 柯里化后的函数 
// let curried = _.curry(getSum)
// console.log(curried(1,2,3))
// console.log(curried(1)(2,3))

// const _ =require('lodash')
// const match = _.curry(function (reg, str) {
//      return str.match(reg) 
//     })
//     const haveSpace = match(/\s+/g) 
//     const haveNumber = match(/\d+/g)
//     // console.log(haveSpace('hello w orld'))//没有就是null
//     //  console.log(haveNumber('25$dd444 555'))

//      const filter = _.curry(function (func, array) { 
//          return array.filter(func) 
//         })


    
    
    // const findSpace = filter(haveSpace)
    // console.log(filter(haveSpace, ['John Connor', 'John_Donne']))
    // console.log(filter(haveSpace)(['John Connor', 'John_Donne']))
       
    // console.log(findSpace( ['John Connor', 'John_Donne']))

// const _ =require('lodash')
// // 要柯里化的函数
//  function getSum (a, b, c) { return a + b + c }
// // 柯里化后的函数 
// let curried = _.curry(getSum) 
// // 测试 
// console.log(curried(1,2,3))
// console.log(curried(1)(2,3))
// console.log(curried(1, 2)(3))
// curried(1, 2, 3) 
// curried(1)(2)(3) 
// curried(1, 2)(3)
// 柯里化模拟
// function curry (func) { 
//     return function curriedFn (...args) { 
//     // 判断实参和形参的个数 
//     if (args.length < func.length) { 
//         return function () { 
//             return curriedFn(...args.concat(Array.from(arguments))) 
//           }
//          }
//              // 实参和形参个数相同，调用 func，返回结果 
//             return func(...args) 
//          } }

// 函数组合
// 演示
// function compose(f,g){
//     return function (value){
//        return f(g(value))
//     }
// }
// function reverse (array){
//     return array.reverse()
// }
// function first(array){
//     return array[0]
// }
// const last = compose(first,reverse)
// console.log(last([1,2,3,4,5]))

// lodash 中的组合函数
//   flow()
//   flowRight()
// const _ = require('lodash')
// const reverse = arr =>arr.reverse()
// const first = arr =>arr[0]
// const toUpper = s =>s.toUpperCase()
// const f = _.flowRight(toUpper,first,reverse)
// console.log(f(['one','two','three']))

// 模拟组合函数的原理
// function compose (...args){
//     return function(value){
//         return args.reverse().reduce(function(acc,fn){
//                 return fn(acc)
//         },value)
//     }
// }
// ES6 
// const compose = (...fns) => value => fns.reverse().reduce((acc, fn) => fn(acc), value)
// const f = compose(toUpper,first,reverse)
// console.log(f(['one','two','three']))

// 结合律
// const _ = require('lodash')
// const f =_.flowRight(_.toUpper,_.first,_.reverse)
// const f1=_.flowRight(_.toUpper,_.flowRight(_.first,_.reverse))
// console.log(f(['one','two','three']))
// console.log(f1(['one','two','three']))

// 函数结合 调试
// const _ = require('lodash')
// // _.split()
// const split = _.curry((sep,str)=>_.split(str,sep))
// _.toLower()
// const log = v =>{
//     console.log(v)
//     return v
// }
// const trace = _.curry((tag, v) => { 
//     console.log(tag, v)
//      return v 
//     })
// const map = _.curry((sep,array) =>_.map(array,sep))
// const join =_.curry((sep,array) =>_.join(array,sep))
// const f = _.flowRight(join('-'),map(_.toLower), split(' '))

// console.log(f('AHJK DFG DF'))


const _ = require('lodash')
